package org.example.core;

import java.util.ArrayList;
import java.util.List;

/**
 * 文件操作类 - 实现基本的文件操作命令
 */
public class FileOperations {
    private DiskEmulator disk; // 磁盘模拟器，用于读写磁盘块
    private FATManager fat; // FAT管理器，用于管理文件分配表

    public FileOperations(DiskEmulator disk, FATManager fat) {
        this.disk = disk;
        this.fat = fat;
    }

    /**
     * 列出目录内容
     * @param directoryBlock 目录块号
     * @return 目录项列表
     */
    public List<DirectoryEntry> listDirectory(int directoryBlock) {
        List<DirectoryEntry> entries = new ArrayList<>(); // 目录项列表

        try {
            byte[] dirBlock = disk.readBlock(directoryBlock); // 读取目录块数据

            for (int i = 0; i < 8; i++) {
                byte[] entryData = new byte[8]; // 目录项数据
                System.arraycopy(dirBlock, i * 8, entryData, 0, 8);

                DirectoryEntry entry = DirectoryEntry.fromBytes(entryData);
                if (!entry.isEmpty()) {
                    entries.add(entry);
                }
            }
        } catch (Exception e) {
            System.err.println("读取目录失败: " + e.getMessage());
        }

        return entries;
    }

    /**
     * 创建文件
     * @param directoryBlock 目录块号
     * @param name 文件名
     * @param ext 文件扩展名
     * @param attributes 文件属性
     * @return 是否创建成功
     */
    public boolean createFile(int directoryBlock, String name, String ext, byte attributes) {
        try {

            byte[] dirBlock = disk.readBlock(directoryBlock); // 读取目录块数据

            // 查找空闲目录项
            int freeSlot = -1;
            for (int i = 0; i < 8; i++) {
                byte[] entryData = new byte[8];
                System.arraycopy(dirBlock, i * 8, entryData, 0, 8);

                DirectoryEntry entry = DirectoryEntry.fromBytes(entryData);
                if (entry.isEmpty()) {
                    freeSlot = i;
                    break;
                }
            }

            if (freeSlot == -1) {
                System.err.println("目录已满，无法创建文件");
                return false;
            }

            // 分配磁盘块
            int newBlock = fat.allocateBlock();
            if (newBlock == -1) {
                System.err.println("磁盘空间不足，无法创建文件");
                return false;
            }

            // 创建目录项
            DirectoryEntry newEntry = new DirectoryEntry(); // 创建新目录项
            newEntry.setName(name); // 设置文件名
            newEntry.setExtension(ext); // 设置文件扩展名
            newEntry.setAttributes(attributes); // 设置文件属性
            newEntry.setStartBlock((byte) newBlock); // 设置文件起始块号
            newEntry.setLength((byte) 1); // 初始长度为1块，因为文件至少有一个数据块

            // 写入目录项
            byte[] entryData = newEntry.toBytes();
            System.arraycopy(entryData, 0, dirBlock, freeSlot * 8, 8);
            disk.writeBlock(directoryBlock, dirBlock);

            // 初始化文件内容块
            byte[] fileBlock = new byte[disk.getBlockSize()];
            disk.writeBlock(newBlock, fileBlock);

            // 保存FAT表
            fat.saveFAT();

            System.out.println("文件创建成功: " + newEntry.getFullName());
            return true;

        } catch (Exception e) {
            System.err.println("创建文件失败: " + e.getMessage());
            return false;
        }
    }

    /**
     * 创建目录
     * @param parentBlock 父目录块号
     * @param name 目录名
     * @return 是否创建成功
     */
    public boolean createDirectory(int parentBlock, String name) {
        try {
            byte[] parentDirBlock = disk.readBlock(parentBlock); // 读取父目录块数据

            // 查找空闲目录项
            int freeSlot = -1;
            for (int i = 0; i < 8; i++) {
                byte[] entryData = new byte[8];
                System.arraycopy(parentDirBlock, i * 8, entryData, 0, 8);

                DirectoryEntry entry = DirectoryEntry.fromBytes(entryData);
                if (entry.isEmpty()) {
                    freeSlot = i;
                    break;
                }
            }

            if (freeSlot == -1) {
                System.err.println("目录已满，无法创建子目录");
                return false;
            }

            // 分配磁盘块用于新目录
            int newDirBlock = fat.allocateBlock();
            if (newDirBlock == -1) {
                System.err.println("磁盘空间不足，无法创建目录");
                return false;
            }

            // 初始化新目录块
            byte[] newDirData = new byte[disk.getBlockSize()];
            for (int i = 0; i < 8; i++) {
                DirectoryEntry emptyEntry = DirectoryEntry.createEmpty();
                byte[] entryData = emptyEntry.toBytes();
                System.arraycopy(entryData, 0, newDirData, i * 8, 8);
            }
            disk.writeBlock(newDirBlock, newDirData);

            // 创建目录项
            DirectoryEntry newEntry = new DirectoryEntry();
            newEntry.setName(name);
            newEntry.setExtension("");
            newEntry.setAttributes(DirectoryEntry.DIRECTORY);
            newEntry.setStartBlock((byte) newDirBlock);
            newEntry.setLength((byte) 1);

            // 写入目录项
            byte[] entryData = newEntry.toBytes();
            System.arraycopy(entryData, 0, parentDirBlock, freeSlot * 8, 8);
            disk.writeBlock(parentBlock, parentDirBlock);

            // 保存FAT表
            fat.saveFAT();

            System.out.println("目录创建成功: " + name);
            return true;

        } catch (Exception e) {
            System.err.println("创建目录失败: " + e.getMessage());
            return false;
        }
    }

    /**
     * 删除文件或空目录
     * @param directoryBlock 目录块号
     * @param name 文件名或目录名
     * @return 是否删除成功
     */
    public boolean deleteEntry(int directoryBlock, String name) {
        try {
            byte[] dirBlock = disk.readBlock(directoryBlock);

            // 查找要删除的目录项
            int targetSlot = -1;
            DirectoryEntry targetEntry = null;

            for (int i = 0; i < 8; i++) {
                byte[] entryData = new byte[8];
                System.arraycopy(dirBlock, i * 8, entryData, 0, 8);

                DirectoryEntry entry = DirectoryEntry.fromBytes(entryData);
                if (!entry.isEmpty() && entry.getName().equals(name)) {
                    targetSlot = i;
                    targetEntry = entry;
                    break;
                }
            }

            if (targetSlot == -1) {
                System.err.println("未找到文件或目录: " + name);
                return false;
            }

            // 如果是目录，检查是否为空
            if (targetEntry.isDirectory()) {
                List<DirectoryEntry> subEntries = listDirectory(targetEntry.getStartBlock() & 0xFF);
                boolean hasEntries = false;

                for (DirectoryEntry entry : subEntries) {
                    if (!entry.isEmpty()) {
                        hasEntries = true;
                        break;
                    }
                }

                if (hasEntries) {
                    System.err.println("目录非空，无法删除: " + name);
                    return false;
                }
            }

            // 释放磁盘块
            int currentBlock = targetEntry.getStartBlock() & 0xFF;
            while (currentBlock != FATManager.END_OF_FILE && currentBlock != 0) {
                int nextBlock = fat.getNextBlock(currentBlock);
                fat.freeBlock(currentBlock);
                currentBlock = nextBlock;
            }

            // 删除目录项
            DirectoryEntry emptyEntry = DirectoryEntry.createEmpty();
            byte[] emptyData = emptyEntry.toBytes();
            System.arraycopy(emptyData, 0, dirBlock, targetSlot * 8, 8);
            disk.writeBlock(directoryBlock, dirBlock);

            // 保存FAT表
            fat.saveFAT();

            System.out.println("删除成功: " + name);
            return true;

        } catch (Exception e) {
            System.err.println("删除失败: " + e.getMessage());
            return false;
        }
    }
}
